package ui;

import javax.swing.JPanel;

import database.Schema;
import database.constraint.CheckConstraint;
import database.constraint.Constraint;
import database.constraint.ListBusinessConstraint;
import database.constraint.PrimaryKeyConstraint;
import database.constraint.ReferenceConstraint;
import database.constraint.UniqueConstraint;
import database.constraint.join.ListJoin;
import database.relation.Relation;
import database.relation.Table;
import javax.swing.JLabel;
import javax.swing.JSeparator;
import java.awt.Font;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.border.MatteBorder;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;

import java.awt.Color;
import java.util.ArrayList;

import javax.swing.table.DefaultTableModel;

import java.awt.Rectangle;
import javax.swing.JButton;
import javax.swing.JTextArea;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.ImageIcon;

import parser.ConstraintParser;

import constraint.*;
import constraint.join.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

public class TableInfoPanel extends JPanel {
	Table table;
	ArrayList<Table> lsTable;
	ArrayList<Relation> lsRelation;
	
	private JTable tableListConstraint;
	Object[][] listRowConstraint;
	
	JScrollPane scrollPane;
	JTextArea textAreaEnterConstraint;
	JButton btnSave;
	JButton btnAddtableconstraint;
	JLabel lblSavedMess;
	
	private String implodeArray(String owner, ArrayList<String> listAtt) {
		String result = "";
		
		if(listAtt.size() == 1) {
			result = "[" + owner + "." + listAtt.get(0) + "]";
			return result;
		}
		
		for(int i = 0; i < listAtt.size(); i++) {
			if(i == 0) {
				result = "[" + owner + "." + listAtt.get(i);
			} else if (i == listAtt.size() - 1) {
				result += ", " + owner + "." + listAtt.get(i) + "]";
			} else {
				result += ", " + owner + "." + listAtt.get(i);
			}
			
		}
		return result;
	}
	
	/**
	 * Create the panel.
	 */
	public TableInfoPanel(Table tb, ArrayList<Table> lsTb, ArrayList<Relation> lsRel) {
		table = tb;
		lsTable = lsTb;
		lsRelation = lsRel;
		
		ArrayList<Constraint> listConstraint = tb.getListConstraint();
		
		listRowConstraint = new Object[listConstraint.size()][];
		
		for(int i = 0; i < listConstraint.size(); i++) {
			Constraint c = listConstraint.get(i);
			switch (c.type) {
			case 1:
				//ref
				ReferenceConstraint rc1 = (ReferenceConstraint) c;
				String[] row1 = new String[5];
				row1[0] = "Foreign Key";
				row1[1] = null;
				row1[2] = implodeArray(rc1.getOwnerTable(), rc1.getOwnerAtt());
				row1[3] = implodeArray(rc1.getRefTable(), rc1.getRefAtt());
				row1[4] = null;
				listRowConstraint[i] = row1;
				break;

			case 2:
				PrimaryKeyConstraint rc2 = (PrimaryKeyConstraint) c;
				String[] row2 = new String[5];
				row2[0] = "Primary Key";
				row2[1] = implodeArray(table.getTableName(), rc2.getKey());
				row2[2] = null;
				row2[3] = null;
				row2[4] = null;
				listRowConstraint[i] = row2;
				//pk
				break;
			case 3:
			    UniqueConstraint rc3 = (UniqueConstraint) c;
			    String[] row3 = new String[5];
			    row3[0] = "Unique";
			    row3[1] = implodeArray(table.getTableName(), rc3.getAttribute());
			    row3[2] = null;
			    row3[3] = null;
			    row3[4] = null;
			    listRowConstraint[i] = row3;
			    //unique
			    break;
			case 4:
			    CheckConstraint rc4 = (CheckConstraint) c;
			    String[] row4 = new String[5];
			    row4[0] = "Check";
			    row4[1] = implodeArray(table.getTableName(), rc4.getAttribute());
			    row4[2] = null;
			    row4[3] = null;
			    row4[4] = rc4.getCondition();
			    listRowConstraint[i] = row4;
			    //check
			    break;
			}
		} 
		
		this.setBounds(0, 0, 258, 655);
		setLayout(null);
		
		JLabel lblTableName = new JLabel(table.getTableName());
		lblTableName.setFont(new Font("Tahoma", Font.PLAIN, 15));
		lblTableName.setBounds(0, 0, 258, 31);
		add(lblTableName);
		
		JSeparator separator = new JSeparator();
		separator.setBounds(0, 42, 258, 24);
		add(separator);
		
		JLabel lblListConstraints = new JLabel("Danh sách các ràng buộc của bảng:");
		lblListConstraints.setBounds(0, 42, 258, 24);
		add(lblListConstraints);
		
		btnAddtableconstraint = new JButton("");
		btnAddtableconstraint.setToolTipText("thêm ràng buộc cho bảng");
		btnAddtableconstraint.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				DefaultTableModel model = (DefaultTableModel) tableListConstraint.getModel();
				int numOfRow = model.getRowCount();
				
				tableListConstraint.setVisible(false);
				model.insertRow(numOfRow, new String[] {"", "", "", "", ""});
				tableListConstraint.setVisible(true);
			}
		});
		btnAddtableconstraint.setIcon(new ImageIcon(TableInfoPanel.class.getResource("/resource/add.png")));
		btnAddtableconstraint.setBounds(233, 53, 15, 15);
		add(btnAddtableconstraint);
		
		JScrollPane scrollPaneListConstraint = new JScrollPane();
		scrollPaneListConstraint.setBounds(0, 77, 258, 281);
		add(scrollPaneListConstraint);
		
		tableListConstraint = new JTable();
		tableListConstraint.setBounds(new Rectangle(0, 0, 1000, 281));
		tableListConstraint.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		
		DefaultTableModel _model = new DefaultTableModel(
			listRowConstraint,
			new String[] {
				"Loại", "Thuộc tính", "Nguồn tham chiếu", "Đích tham chiếu", "Thông tin thêm"
			}
		);
		
		_model.addTableModelListener(new TableModelListener() {
			
			@Override
			public void tableChanged(TableModelEvent e) {
				DefaultTableModel model = (DefaultTableModel) tableListConstraint.getModel();
				int numOfRow = model.getRowCount();
				String _Type = (String) model.getValueAt(numOfRow - 1, 0);
				String _Attribute = (String) model.getValueAt(numOfRow - 1, 1);
				String _Source = (String) model.getValueAt(numOfRow - 1, 2);
				String _Destination = (String) model.getValueAt(numOfRow - 1, 3);
				String _Infomation = (String) model.getValueAt(numOfRow - 1, 4);
				
				if(_Type.equals("") && _Attribute.equals("") && _Source.equals("") && _Destination.equals("") && _Infomation.equals("")) {
					return;
				}
				
				if(_Type.equalsIgnoreCase("Foreign Key")) {
					if(_Source.equals("") || _Destination.equals("")) {
						return;
					}
					
					String[] listAttOwn = _Source.split(",");
					
					String[] listAttRef = _Destination.split(",");
					
					ReferenceConstraint fk = new ReferenceConstraint();
					
					if(listAttOwn.length == 1) {
						//[table.attt]
						String tbAtt = _Source.substring(1, _Source.length() - 1);
						
						tbAtt = tbAtt.replace('.', ',');
						
						String[] _tbAtt = tbAtt.split(",");
						
						fk.setOwnerTable(_tbAtt[0]);
						
						fk.getOwnerAtt().add(_tbAtt[1]);
					}
					
					if(listAttOwn.length == 2) {
						//[table.att, table.att]
						String tbAtt = listAttOwn[0].substring(1);
						
						tbAtt = tbAtt.replace('.', ',');
						
						String[] _tbAtt = tbAtt.split(",");
						
						fk.setOwnerTable(_tbAtt[0]);
						
						fk.getOwnerAtt().add(_tbAtt[1]);
						
						tbAtt = listAttOwn[1].substring(1, listAttOwn[1].length() - 1);
						
						tbAtt = tbAtt.replace('.', ',');
						
						_tbAtt = tbAtt.split(",");
						
						fk.getOwnerAtt().add(_tbAtt[1]);
					}
					
					if(listAttOwn.length > 2) {
						//[table.att, table.att, ..., table.att]
						String tbAtt = listAttOwn[0].substring(1);
						
						tbAtt = tbAtt.replace('.', ',');
						
						String[] _tbAtt = tbAtt.split(",");
						
						fk.setOwnerTable(_tbAtt[0]);
						
						fk.getOwnerAtt().add(_tbAtt[1]);
						
						for(int i = 1; i < listAttOwn.length - 1; i++) {
							tbAtt = listAttOwn[i].substring(1);
							
							tbAtt = tbAtt.replace('.', ',');
							
							_tbAtt = tbAtt.split(",");
							
							fk.getOwnerAtt().add(_tbAtt[1]);
						}
						
						tbAtt = listAttOwn[listAttOwn.length - 1].substring(1, listAttOwn[listAttOwn.length - 1].length() - 1);
						
						tbAtt = tbAtt.replace('.', ',');
						
						_tbAtt = tbAtt.split(",");
						
						fk.getOwnerAtt().add(_tbAtt[1]);
					}
					
					
					
					if(listAttRef.length == 1) {
						//[table.attt]
						String tbAtt = _Destination.substring(1, _Destination.length() - 1);
						
						tbAtt = tbAtt.replace('.', ',');
						
						String[] _tbAtt = tbAtt.split(",");
						
						fk.setRefTable(_tbAtt[0]);
						
						fk.getRefAtt().add(_tbAtt[1]);
					}
					
					if(listAttRef.length == 2) {
						//[table.att, table.att]
						String tbAtt = listAttRef[0].substring(1);
						
						tbAtt = tbAtt.replace('.', ',');
						
						String[] _tbAtt = tbAtt.split(",");
						
						fk.setRefTable(_tbAtt[0]);
						
						fk.getRefAtt().add(_tbAtt[1]);
						
						tbAtt = listAttRef[1].substring(1, listAttRef[1].length() - 1);
						
						tbAtt = tbAtt.replace('.', ',');
						
						_tbAtt = tbAtt.split(",");
						
						fk.getRefAtt().add(_tbAtt[1]);
					}
					
					if(listAttRef.length > 2) {
						//[table.att, table.att, ..., table.att]
						String tbAtt = listAttRef[0].substring(1);
						
						tbAtt = tbAtt.replace('.', ',');
						
						String[] _tbAtt = tbAtt.split(",");
						
						fk.setRefTable(_tbAtt[0]);
						
						fk.getRefAtt().add(_tbAtt[1]);
						
						for(int i = 1; i < listAttRef.length - 1; i++) {
							tbAtt = listAttRef[i].substring(1);
							
							tbAtt = tbAtt.replace('.', ',');
							
							_tbAtt = tbAtt.split(",");
							
							fk.getRefAtt().add(_tbAtt[1]);
						}
						
						tbAtt = listAttRef[listAttRef.length - 1].substring(1, listAttRef[listAttRef.length - 1].length() - 1);
						
						tbAtt = tbAtt.replace('.', ',');
						
						_tbAtt = tbAtt.split(",");
						
						fk.getRefAtt().add(_tbAtt[1]);
					}
					
					  //update table index
					if (updateTableIndex(fk)) {
					    table.getListConstraint().add(fk);
					    // project da bi thay doi
			            Schema.alreadyAnalysis = false;
					} else {
					    return;
					}
					
//					table.getListConstraint().add(fk);
				}
				
				if(_Type.equalsIgnoreCase("Primary Key")) {
					if(_Attribute.equals("")) {
						return;
					}
					
					String[] listAtt = _Attribute.split(",");
					
					if(listAtt.length == 1) {
						//  [table.attribute_name]
						PrimaryKeyConstraint pk = new PrimaryKeyConstraint();
						
						String tbAtt = _Attribute.substring(1, _Attribute.length() - 1);
						
						tbAtt = tbAtt.replace('.', ',');
						
						String[] _tbAtt = tbAtt.split(",");
						
						pk.getKey().add(_tbAtt[1]);
						
						table.getListConstraint().add(pk);
						  // project da bi thay doi
			            Schema.alreadyAnalysis = false;
					}
					
					if(listAtt.length == 2) {
						//  [table.attribute, table.attribute]
						PrimaryKeyConstraint pk = new PrimaryKeyConstraint();
						
						String tbAtt = listAtt[0].substring(1);
						
						tbAtt = tbAtt.replace('.', ',');
						
						String[] _tbAtt = tbAtt.split(",");
						
						pk.getKey().add(_tbAtt[1]);
						
						tbAtt = listAtt[1].substring(1, listAtt[1].length() - 1);
						tbAtt = tbAtt.replace('.', ',');
						_tbAtt = tbAtt.split(",");
						pk.getKey().add(_tbAtt[1]);
						
						table.getListConstraint().add(pk);
						  // project da bi thay doi
			            Schema.alreadyAnalysis = false;
					}
					
					if(listAtt.length > 2) {
						//  [attribute, attribute, ..., attribute]
						PrimaryKeyConstraint pk = new PrimaryKeyConstraint();
						
						String tbAtt = listAtt[0].substring(1);
						
						tbAtt = tbAtt.replace('.', ',');
						
						String[] _tbAtt = tbAtt.split(",");
						
						pk.getKey().add(_tbAtt[1]);
						
						for(int i = 1; i < listAtt.length - 1; i++) {
							tbAtt = listAtt[i].substring(1);
							tbAtt = tbAtt.replace('.', ',');
							_tbAtt = tbAtt.split(",");
							pk.getKey().add(_tbAtt[1]);
						}
						
						tbAtt = listAtt[listAtt.length - 1].substring(1, listAtt[listAtt.length - 1].length() - 1);
						
						tbAtt = tbAtt.replace('.', ',');
						
						_tbAtt = tbAtt.split(",");
						
						pk.getKey().add(_tbAtt[1]);
						
						table.getListConstraint().add(pk);
						// project da bi thay doi
			            Schema.alreadyAnalysis = false;
					}
				}
                
                
                if(_Type.equalsIgnoreCase("Unique")) {
                    if(_Attribute.equals("")) {
                        return;
                    }
                    
                    String[] listAtt = _Attribute.split(",");
                    
                    if(listAtt.length == 1) {
                        //  [table.attribute_name]
                        UniqueConstraint u = new UniqueConstraint();
                        
                        String tbAtt = _Attribute.substring(1, _Attribute.length() - 1);
                        
                        tbAtt = tbAtt.replace('.', ',');
                        
                        String[] _tbAtt = tbAtt.split(",");
                        
                        u.getAttribute().add(_tbAtt[1]);
                        
                        table.getListConstraint().add(u);
                        // project da bi thay doi
                        Schema.alreadyAnalysis = false;
                    }
                    
                    if(listAtt.length == 2) {
                        //  [table.attribute, table.attribute]
                        UniqueConstraint u = new UniqueConstraint();
                        
                        String tbAtt = listAtt[0].substring(1);
                        
                        tbAtt = tbAtt.replace('.', ',');
                        
                        String[] _tbAtt = tbAtt.split(",");
                        
                        u.getAttribute().add(_tbAtt[1]);
                        
                        tbAtt = listAtt[1].substring(1, listAtt[1].length() - 1);
                        tbAtt = tbAtt.replace('.', ',');
                        _tbAtt = tbAtt.split(",");
                        u.getAttribute().add(_tbAtt[1]);
                        table.getListConstraint().add(u);
                        // project da bi thay doi
                        Schema.alreadyAnalysis = false;
                    }
                    
                    if(listAtt.length > 2) {
                        //  [attribute, attribute, ..., attribute]
                        UniqueConstraint u = new UniqueConstraint();
                        
                        String tbAtt = listAtt[0].substring(1);
                        
                        tbAtt = tbAtt.replace('.', ',');
                        
                        String[] _tbAtt = tbAtt.split(",");
                        
                        u.getAttribute().add(_tbAtt[1]);
                        
                        for(int i = 1; i < listAtt.length - 1; i++) {
                            tbAtt = listAtt[i].substring(1);
                            tbAtt = tbAtt.replace('.', ',');
                            _tbAtt = tbAtt.split(",");
                            u.getAttribute().add(_tbAtt[1]);
                        }
                        
                        tbAtt = listAtt[listAtt.length - 1].substring(1, listAtt[listAtt.length - 1].length() - 1);
                        
                        tbAtt = tbAtt.replace('.', ',');
                        
                        _tbAtt = tbAtt.split(",");
                        
                        u.getAttribute().add(_tbAtt[1]);
                        table.getListConstraint().add(u);
                        // project da bi thay doi
                        Schema.alreadyAnalysis = false;
                    }
                }
                
                if(_Type.equalsIgnoreCase("Check")) {
                    if(_Attribute.equals("")) {
                        return;
                    }
                    
                    String[] listAtt = _Attribute.split(",");
                    
                    if(listAtt.length == 1) {
                        //  [table.attribute_name]
                        CheckConstraint c = new CheckConstraint();
                        
                        c.setCondition(_Infomation);
                        
                        String tbAtt = _Attribute.substring(1, _Attribute.length() - 1);
                        
                        tbAtt = tbAtt.replace('.', ',');
                        
                        String[] _tbAtt = tbAtt.split(",");
                        
                        c.getAttribute().add(_tbAtt[1]);
                        
                        table.getListConstraint().add(c);
                        // project da bi thay doi
                        Schema.alreadyAnalysis = false;
                    }
                    
                    if(listAtt.length == 2) {
                        //  [table.attribute, table.attribute]
                        CheckConstraint c = new CheckConstraint();
                        
                        c.setCondition(_Infomation);
                        
                        String tbAtt = listAtt[0].substring(1);
                        
                        tbAtt = tbAtt.replace('.', ',');
                        
                        String[] _tbAtt = tbAtt.split(",");
                        
                        c.getAttribute().add(_tbAtt[1]);
                        
                        tbAtt = listAtt[1].substring(1, listAtt[1].length() - 1);
                        tbAtt = tbAtt.replace('.', ',');
                        _tbAtt = tbAtt.split(",");
                        c.getAttribute().add(_tbAtt[1]);
                        table.getListConstraint().add(c);
                        // project da bi thay doi
                        Schema.alreadyAnalysis = false;
                    }
                    
                    if(listAtt.length > 2) {
                        //  [attribute, attribute, ..., attribute]
                        CheckConstraint c = new CheckConstraint();
                        
                        c.setCondition(_Infomation);
                        
                        String tbAtt = listAtt[0].substring(1);
                        
                        tbAtt = tbAtt.replace('.', ',');
                        
                        String[] _tbAtt = tbAtt.split(",");
                        
                        c.getAttribute().add(_tbAtt[1]);
                        
                        for(int i = 1; i < listAtt.length - 1; i++) {
                            tbAtt = listAtt[i].substring(1);
                            tbAtt = tbAtt.replace('.', ',');
                            _tbAtt = tbAtt.split(",");
                            c.getAttribute().add(_tbAtt[1]);
                        }
                        
                        tbAtt = listAtt[listAtt.length - 1].substring(1, listAtt[listAtt.length - 1].length() - 1);
                        
                        tbAtt = tbAtt.replace('.', ',');
                        
                        _tbAtt = tbAtt.split(",");
                        
                        c.getAttribute().add(_tbAtt[1]);
                        table.getListConstraint().add(c);
                        // project da bi thay doi
                        Schema.alreadyAnalysis = false;
                    }
                }
			}
		});
		

		tableListConstraint.setModel(_model);
		
		tableListConstraint.setBorder(new MatteBorder(1, 1, 1, 1, (Color) new Color(0, 0, 0)));
		scrollPaneListConstraint.setViewportView(tableListConstraint);
		
		JButton btnMoreConstraint = new JButton("Thêm ràng buộc");
		btnMoreConstraint.setToolTipText("thêm những loại ràng buộc khác với những loại ở trên");
		btnMoreConstraint.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if(scrollPane.isVisible()) {
					scrollPane.setVisible(false);
				} else {
					scrollPane.setVisible(true);
				}
			}
		});
		
		btnMoreConstraint.setBounds(10, 366, 140, 23);
		add(btnMoreConstraint);
		
		scrollPane = new JScrollPane();
		scrollPane.setBounds(0, 397, 258, 204);
		add(scrollPane);
		
		textAreaEnterConstraint = new JTextArea();
		textAreaEnterConstraint.addKeyListener(new KeyAdapter() {
		    @Override
		    public void keyPressed(KeyEvent KE) {
		        lblSavedMess.setText("");
		    }
		});
		scrollPane.setViewportView(textAreaEnterConstraint);
		scrollPane.setVisible(false);
		textAreaEnterConstraint.setText(table.txtConstraint);
		
		btnSave = new JButton("Lưu");
		btnSave.setToolTipText("lưu ràng buộc");
		btnSave.addActionListener(new ActionListener() {
		    public void actionPerformed(ActionEvent e) {
		          // luu business constraint o day
		        
		          // xu ly so bo
		        String strCons = textAreaEnterConstraint.getText().replace('\n', ' ');
		        if (strCons.length() > 1) {
                    String endC = strCons.substring(strCons.length()-1, strCons.length());
                    if (!endC.equals(";")) {
                        strCons += ";";
                    }
		        } else {
		            if (strCons.equals(";")) {
		                strCons = " ;";
		            } else {
		                strCons += " ;";
		            }
		        }
                
		          // xu ly: parse tung constraint mot
		        ConstraintParser cp = new ConstraintParser();
		        ListBusinessConstraint lsConstraint = new ListBusinessConstraint();
		        String[] lsStrCons = strCons.split(";");
		        int n = lsStrCons.length;
		        boolean isError = false;
		        String errorMess = "";
		        
		        for (int i = 0; i < n; i++) {
		            if (isError) {
		                break;
		            }
		            
		            String strConstraint = lsStrCons[i].trim();
		            if (strConstraint.equals("")) {
		                continue;
		            }
		            
    		        try {
                        constraint.Constraint c = cp.parse(strConstraint);
                        int type = -1;
                        String[] lsAtts = table.getListColumn();
                        
                        if (c != null)  {
                            type = c.type;
                        }
                        
                        switch (type) {
                            case 1:
                                Constraint_v1 c1 = (Constraint_v1) c;
                                String left = c1.idName.replace('.', ',');
                                String[] tmpStr = left.split(",");
                                
                                String tb = tmpStr[0];
                                
                                if (!tb.equals(table.getTableName())) {
                                    isError = true;
                                    errorMess = "Bảng không hợp lệ";
                                }
                                
                                if (!isError) {
                                    int k1 = 0;
                                    boolean found1 = false;
                                    while (!found1 && k1 < lsAtts.length) {
                                        if (tmpStr[1].equals(lsAtts[k1])) {
                                            found1 = true;
                                        }
                                        k1++;
                                    }
                                    if (!found1) {
                                        isError = true;
                                        errorMess = "Cột không hợp lệ";
                                    }
                                }
                                  // ko add nhung constraint thuoc loai 1
                                break;
                            case 2:
                                Constraint_v2 c2 = (Constraint_v2) c;
                                
                                  // ktra bang cua ve trai co phai la bang dang xet hay khong
                                  // update index
                                errorMess = checkListElements(c2.left);
                                if (!errorMess.equals("")) {
                                    isError = true;
                                } else {
                                      // ktra bang cua ve phai co phai la bang dang xet hay khong
                                      // update index
                                    errorMess = checkListElements(c2.right);
                                    if (!errorMess.equals("")) {
                                        isError = true;
                                    }
                                }
                                
                                if (!isError && c2.op.equals("=")) {
                                      // add constraint loai 2 vao list constraint
                                    lsConstraint.add(c2);
                                }
                                break;
                            case 3:
                                Constraint_v3 c3 = (Constraint_v3) c;
                                Group g = c3.leftGroup;
                                
                                  // kiem tra cai join - loai 3 khong cho co join
                                if (g.join.size() > 0) {
                                    isError = true;
                                    errorMess = "Chỉ cho phép một bảng";
                                }
                                
                                  // kiem tra cai group
                                if (!isError) {
                                    errorMess = checkGroup(g);
                                    if (!errorMess.equals("")) {
                                        isError = true;
                                    }
                                }
                                
                                if (!isError && c3.op.equals("=")) {
                                      // add constraint loai 2 vao list constraint
                                    lsConstraint.add(c3);
                                }
                                break;
                            case 4:
                                Constraint_v4 c4 = (Constraint_v4) c;
                                
                                  // ktra bang cua ve trai co phai la bang dang xet hay khong
                                  // update index
                                errorMess = checkListExpandElements(c4.left);
                                if (!errorMess.equals("")) {
                                    isError = true;
                                } else {
                                      // ktra bang cua ve phai co phai la bang dang xet hay khong
                                      // update index
                                    errorMess = checkListExpandElements(c4.right);
                                    if (!errorMess.equals("")) {
                                        isError = true;
                                    }
                                }
                                
                                  // ktra cai join
                                if (!isError) {
                                    errorMess = checkJoin(c4.join);
                                    if (!errorMess.equals("")) {
                                        isError = true;
                                    }
                                }
                                
                                if (!isError && c4.op.equals("=")) {
                                 // add constraint loai 2 vao list constraint
                                    lsConstraint.add(c4);
                                }
                                break;
                            case 5:
                                isError = true;
                                errorMess = "Chỉ cho phép một bảng";
                                break;
                            case 6:
                                isError = true;
                                errorMess = "Chỉ cho phép một bảng";
                                break;
                            default:
                                isError = true;
                                errorMess = "Lỗi cú pháp";
                                break;
                        }
                    } catch (Exception ex) {
                        // TODO Auto-generated catch block
                        ex.printStackTrace();
                          // loi cu phap khi parse
                        isError = true;
                        errorMess = "Lỗi không xác định";
                    }
		        }
		        
		        if (!isError) {
		            table.setListBConstraint(lsConstraint);
		            table.txtConstraint = textAreaEnterConstraint.getText();
		              // hien thi success
		            lblSavedMess.setForeground(Color.BLACK);
		            lblSavedMess.setText("Lưu thành công");
		              // project da bi thay doi
		            Schema.alreadyAnalysis = false;
		        } else {
		              // hien thi error
		            lblSavedMess.setForeground(Color.RED);
                    lblSavedMess.setText(errorMess);
		        }
		    }
		});
		btnSave.setBounds(178, 632, 70, 23);
		add(btnSave);
		
		lblSavedMess = new JLabel("");
		lblSavedMess.setBounds(10, 604, 238, 24);
		add(lblSavedMess);
	}
	
	public boolean updateTableIndex(ReferenceConstraint rc) {
	      
	    int i = 0;
	    boolean found = false;
	    boolean found2 = false;
	    String[] lsAtt1;
	    ArrayList<String> lsAtt2;
	      // update index table nguon
	    if (rc.getOwnerTable().equals(table.getTableName())) {
	        rc.ownerTableIndex = table.index;
	    } else {
	        return false;
	    }
	    
	      // update index tap thuoc tinh nguon
	    lsAtt1 = table.getListColumn();
	    lsAtt2 = rc.getOwnerAtt();
	    for (int j = 0; j < lsAtt2.size(); j++) {
	        int k = 0;
	        String str = lsAtt2.get(j);
	        found2 = false;
	        while (!found2 && k < lsAtt1.length) {
	            found2 = str.equals(lsAtt1[k]);
	            k++;
	        }
	        if (found2) {
	            rc.ownerAttIndex.add(k-1);
	        } else {
	            return false;
	        }
	    }
	    
	      // update index table dich
        i = 0;
        found = false;
        while (!found && i < lsTable.size()) {
            found = rc.getRefTable().equals(lsTable.get(i).getTableName());
            i++;
        }
        if (found) {
            rc.refTableIndex = i - 1;
        } else {
            return false;
        }
        
          // update index tap thuoc tinh dich
        lsAtt1 = lsTable.get(i-1).getListColumn();
        lsAtt2 = rc.getRefAtt();
        for (int j = 0; j < lsAtt2.size(); j++) {
            int k = 0;
            String str = lsAtt2.get(j);
            found2 = false;
            while (!found2 && k < lsAtt1.length) {
                found2 = str.equals(lsAtt1[k]);
                k++;
            }
            if (found2) {
                rc.refAttIndex.add(k-1);
            } else {
                return false;
            }
        }
	    
	    return true;
    }
	
	public String checkListElements(ArrayList<Element> lsE) {
	    boolean isError = false;
	    String errorMess = "";
	    String[] lsAtts = table.getListColumn();
	    String[] tmp_ArrStr;
	    
	    int j = 0;
	    while (!isError && j < lsE.size()) {
            tmp_ArrStr = lsE.get(j).idName.replace('.', ',').split(",");
            if (!tmp_ArrStr[0].equals(table.getTableName())) {
                isError = true;
                errorMess = "Bảng không hợp lệ";
            } else {
                int k = 0;
                boolean found = false;
                while (!found && k < lsAtts.length) {
                    if (tmp_ArrStr[1].equals(lsAtts[k])) {
                        found = true;
                        lsE.get(j).index = lsRelation.get(table.index).get(k);
                        lsE.get(j).tableIndex = table.index;
                    }
                    k++;
                }
                if (!found) {
                    isError = true;
                    errorMess = "Cột không hợp lệ";
                }
            }
            j++;
        }
	    
	    return errorMess;
	}
	
	public String checkListExpandElements(ArrayList<Element> lsE) {
        boolean isError = false;
        String errorMess = "";
        String[] lsAtts = table.getListColumn();
        String[] tmp_ArrStr;
        
        int j = 0;
        while (!isError && j < lsE.size()) {
            tmp_ArrStr = lsE.get(j).idName.replace('.', ',').split(",");
            if (!tmp_ArrStr[0].equals(table.getTableName()+"[0]")
                    && !tmp_ArrStr[0].equals(table.getTableName()+"[1]")) {
                isError = true;
                errorMess = "Bảng không hợp lệ";
            } else {
                int k = 0;
                boolean found = false;
                while (!found && k < lsAtts.length) {
                    if (tmp_ArrStr[1].equals(lsAtts[k])) {
                        found = true;
                        lsE.get(j).index = lsRelation.get(table.index).get(k);
                        lsE.get(j).tableIndex = table.index;
                        if (tmp_ArrStr[0].equals(table.getTableName()+"[0]")) {
                            lsE.get(j).expand = 0;
                        } else {
                            lsE.get(j).expand = 1;
                        }
                    }
                    k++;
                }
                if (!found) {
                    isError = true;
                    errorMess = "Cột không hợp lệ";
                }
            }
            j++;
        }
        
        return errorMess;
    }
	
	public String checkJoin(ArrayList<Join> lsJoins) {
	    boolean isError = false;
        String errorMess = "";
        String[] lsAtts = table.getListColumn();
        String[] tmp1_ArrStr;
        String[] tmp2_ArrStr;
        boolean isReverse = false;
        
        int i_gj = 0;
        while (!isError && i_gj < lsJoins.size()) {
            Join join = lsJoins.get(i_gj);
            
              // chuan hoa ve phai va ve trai cua dien kien
            tmp1_ArrStr = join.left.replace('.', ',').split(",");
            tmp2_ArrStr = join.right.replace('.', ',').split(",");
            if (tmp1_ArrStr[0].length() < 3 || tmp1_ArrStr[0].length() < 3) {
                isError = true;
                errorMess = "Điều kiện JOIN không hợp lệ";
            } else {
                int l1 = tmp1_ArrStr[0].length();
                int l2 = tmp1_ArrStr[0].length();
                if (!tmp1_ArrStr[0].substring(0, l1-3).equals(table.getTableName()) 
                        || !tmp2_ArrStr[0].substring(0, l1-3).equals(table.getTableName())) {
                    isError = true;
                    errorMess = "Bảng không hợp lệ";
                } else {
                    tmp1_ArrStr[0] = tmp1_ArrStr[0].substring(l1-3, l1);
                    tmp2_ArrStr[0] = tmp2_ArrStr[0].substring(l2-3, l2);
                }
            }
            
            if (!isError) {
                if (tmp1_ArrStr[0].equals("[0]") && tmp2_ArrStr[0].equals("[1]")) {
                    // do nothing
                } else if (tmp1_ArrStr[0].equals("[1]") && tmp2_ArrStr[0].equals("[0]")) {
                    isReverse = true;
                } else {
                    isError = true;
                    errorMess = "Điều kiện JOIN không hợp lệ";
                }

                
                  // ktra table1 va table2
                if (join.table1.substring(0, join.table1.length()-3).equals(table.getTableName()) 
                        && join.table2.substring(0, join.table2.length()-3).equals(table.getTableName())) {
                    join.indexTable1 = table.index;
                    join.indexTable2 = table.index;
                } else {
                    isError = true;
                    errorMess = "Bảng không hợp lệ trong điều kiện JOIN";
                }
                
                if (!isError) {
                      // ktra thuoc tinh cua table1
                    int k = 0;
                    boolean found = false;
                    String att1;
                    if (!isReverse) {
                        att1 = tmp1_ArrStr[1];
                    } else {
                        att1 = tmp2_ArrStr[1];
                    }
                    
                    while (!found && k < lsAtts.length) {
                        if (att1.equals(lsAtts[k])) {
                            found = true;
                            join.indexAtt1 = lsRelation.get(table.index).get(k);
                        }
                        k++;
                    }
                    if (!found) {
                        isError = true;
                        errorMess = "Cột không hợp lệ trong điều kiện JOIN";
                    }

                    if (!isError) {
                          // ktra thuoc tinh cua table2
                        k = 0;
                        found = false;
                        String att2;
                        if (!isReverse) {
                            att2 = tmp2_ArrStr[1];
                        } else {
                            att2 = tmp1_ArrStr[1];
                        }
                        
                        while (!found && k < lsAtts.length) {
                            if (att2.equals(lsAtts[k])) {
                                found = true;
                                join.indexAtt2 = lsRelation.get(table.index).get(k);
                            }
                            k++;
                        }
                        if (!found) {
                            isError = true;
                            errorMess = "Cột không hợp lệ trong điều kiện JOIN";
                        }
                    }
                }
            }
            i_gj++;
        }
        
        return errorMess;
	}
	
	public String checkGroup(Group g) {
	    boolean isError = false;
        String errorMess = "";
        String[] lsAtts = table.getListColumn();
        String[] tmp_ArrStr;
        
          // kiem tra sub group
        int i = 0;
        while (!isError && i < g.subGroups.size()) {
            SubGroup sg = g.subGroups.get(i);
            errorMess = checkListElements(sg.elements);
            if (!errorMess.equals("")) {
                if (sg.elements.size() == 1) {
                    String[] arrS = sg.elements.get(0).idName.replace('.', ',').split(",");
                    if (arrS[0].equals(table.getTableName()) && arrS[1].equals("*")) {
                        errorMess = "";
                        sg.elements.get(0).index = -2;
                    } else {
                        isError = true;
                    }
                } else {
                    isError = true;
                }
            }
            i++;
        }
        
        if (!isError) {
              // kiem tra thuoc tinh nhom
            int j = 0;
            while (!isError && j < g.groupAtt.size()) {
                tmp_ArrStr = g.groupAtt.get(j).replace('.', ',').split(",");
                
                  // kiem tra table (truoc dau .)
                if (!tmp_ArrStr[0].equals(table.getTableName()+"[0]")
                        && !tmp_ArrStr[0].equals(table.getTableName()+"[1]")) {
                    isError = true;
                    errorMess = "Bảng không hợp lệ trong thuộc tính nhóm";
                }
                
                  // kiem tra thuoc tinh (sau dau .)
                if (!isError) {
                    int k = 0;
                    boolean found = false;
                    while (!found && k < lsAtts.length) {
                        found = tmp_ArrStr[1].equals(lsAtts[k]);
                        k++;
                    }
                    if (!found) {
                        isError = true;
                        errorMess = "Cột không hợp lệ trong thuộc tính nhóm";
                    }
                }
                j++;
            }
            
            if (!isError) {
                errorMess = checkJoin(g.join);
                if (!errorMess.equals("")) {
                    isError = true;
                }
            }
        }
        
        if (!isError) {
            g.indexTables.add(table.index);
        }
        
        return errorMess;
	}
}
